package com.ideaplugin.datamanager.service.statistical.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.TypeUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.google.common.collect.Lists;
import com.ideaplugin.datamanager.model.common.PageResult;
import com.ideaplugin.datamanager.service.UserTableService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

/**
 * Created on 2023/6/13.
 *
 * @author zhaojb
 */
public class CreateController {

    public static void main(String[] args) throws Exception {
        final Class<UserTableService> serviceClass = UserTableService.class;
        final Method[] declaredMethods = ClassUtil.getDeclaredMethods(serviceClass);

        final ArrayList<@Nullable Methods> methods = Lists.newArrayList();

        for (Method declaredMethod : declaredMethods) {
            Methods methods1 = new Methods();
            final Class<?> returnType = declaredMethod.getReturnType();
            if (Collection.class.isAssignableFrom(returnType)) {
                final Type returnType1 = TypeUtil.getReturnType(declaredMethod);
                methods1.setReturnClass(StrFormatter.format("ListResult<{}>", ((Class) TypeUtil.getTypeArgument(returnType1)).getSimpleName()));
                methods1.setReturnType("ListResult");
            } else if (returnType.isAssignableFrom(PageResult.class)) {
                final Type returnType1 = TypeUtil.getReturnType(declaredMethod);
                methods1.setReturnClass(StrFormatter.format("PageResult<{}>", ((Class) TypeUtil.getTypeArgument(returnType1)).getSimpleName()));
                methods1.setReturnType("PageResult");
            } else {
                methods1.setReturnClass(StrFormatter.format("PlainResult<{}>", Convert.wrap(returnType).getSimpleName()));
                methods1.setReturnType("PlainResult");
            }
            methods.add(methods1);

            if (declaredMethod.getParameterTypes().length > 0) {
                methods1.setParamClass(TypeUtil.getParamClass(declaredMethod, 0).getSimpleName());
            }
            methods1.setName(declaredMethod.getName());

        }
        System.out.println(JSON.toJSONString(methods, JSONWriter.Feature.PrettyFormat));

        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);

        cfg.setDirectoryForTemplateLoading(new File("D:\\idea_project\\base-manager\\dwh-data-manager\\src\\test\\java\\com\\ideaplugin\\datamanager\\service\\statistical\\impl"));

        cfg.setDefaultEncoding("UTF-8");

        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        final Template template = cfg.getTemplate("Controller.ftl");
        final Map<String, Object> root = Map.of("className", serviceClass.getSimpleName(), "methods", methods);

        //Writer out = new OutputStreamWriter(System.out);
        Writer out = new OutputStreamWriter(new FileOutputStream("D:\\idea_project\\base-manager\\dwh-data-manager\\src\\main\\java\\com\\ideaplugin\\datamanager\\controller\\" + serviceClass.getSimpleName().replace("Service", "") + "Controller.java"));
        template.process(root, out);

    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Methods {
        private String name;
        private String returnClass;
        private String paramClass = "";
        private String returnType;

    }
}
